package com.shanxia.codec.cmd;

import com.shanxia.codec.Decoder;
import com.shanxia.codec.ProtocolDataBase;
import com.shanxia.codec.enums.DecodeEnum;
import lombok.Data;

import java.util.Objects;

import static com.shanxia.codec.CodeConstant.ONEBYTE_ADDRS;
import static com.shanxia.codec.Decoder.*;

/**
 * S -> C
 * 后台服务器下发充电桩整形工作参数
 * 后台服务器向充电桩下发充电桩整形工作参数命令
 */
@Data
public class Cmd1 extends ProtocolDataBase {

    public static final int MIN_SIZE = 12;

    private int v1;
    private int v2;
    private int type;                        // 类型 [0-查询/ /1-设置]
    private int paramAddr;                   // 设置/查询参数起始地址
    private int paramNum;                    // 设置/查询个数
    private int paramBytes;                  // 设置参数字节数
    private int data;                        // 设置数据 默认4个字节

    public Cmd1(){
        super.setCmd(1);
    }


    public static Cmd1 decodeFromBase(ProtocolDataBase protocolDataBase) {
        Cmd1 cmd = new Cmd1();
        cmd.copyDataFrom(protocolDataBase);
        byte[] dataField = protocolDataBase.getDataField();
        if (dataField.length < MIN_SIZE) {
            cmd.setResult(DecodeEnum.InvalidData);
            return cmd;
        }
        int offset = 0;
        cmd.v1 = getUint16(dataField, offset);
        offset += 2;
        cmd.v2 = getUint16(dataField, offset);
        offset += 2;
        // 1字节类型
        cmd.type = getUint8(dataField[offset++]);
        // 4字节设置/查询参数起始地址
        cmd.paramAddr = bytesToIntLittle(dataField, offset);
        offset += 4;
        // 1字节设置/查询个数
        cmd.paramNum = getUint8(dataField[offset++]);
        // 2字节设置参数字节数
        cmd.paramBytes = getUint16(dataField, offset);
        offset += 2;
        // N字节
        if (Objects.equals(cmd.type, 1)) {
            if (Objects.equals(cmd.paramBytes, 1)) {
                cmd.data = getUint8(dataField[offset]);
            } else if (Objects.equals(cmd.paramBytes, 4)) {
                cmd.data = bytesToIntLittle(dataField, offset);
            }
        }
        return cmd;
    }

    @Override
    public byte[] getDataField() {
        int offset = 0;
        byte[] data = new byte[MIN_SIZE + this.paramBytes];
        getBytesAsUint16(data, offset, this.v1);
        offset += 2;
        getBytesAsUint16(data, offset, this.v2);
        offset += 2;
        data[offset++] = (byte) this.type;
        intToBytesLittle(data, offset, this.paramAddr);
        offset += 4;
        data[offset++] = (byte) this.paramNum;
        getBytesAsUint16(data, 10, this.paramBytes);
        offset += 4;
        switch (this.paramBytes) {
            case 1:
                data[offset] = (byte) this.data;
                break;
            case 4:
                Decoder.intToBytesLittle(data, offset, this.data);
                break;
            default:
                break;
        }
        return data;
    }
}
